<template>
  <div class="tableList flex-column g-box g-inside" :class="{ 'eleFull': isEleFull }">
    <div class="flex-hd">
      <div class="mb10">
        <slot name="formList"></slot>
      </div>
      <div class="toolbarList mb10" :multiples="options.multiples">
        <div class="left">
          <slot name="toolbarLeft">
            <slot name="toolbarLeftStart"></slot>
            <el-button type="primary" size="mini" icon="el-icon-plus" v-if="options.add"
                v-hasPermi="options.add.auth" @click="options.add.click">{{options.add.name || '新增' }}</el-button>
            <el-button type="info" size="mini" icon="el-icon-upload2" v-if="options.import"
              v-hasPermi="options.import.auth" @click="options.import.click">{{options.import.name || '导入' }}</el-button>
            <el-button type="warning" size="mini" icon="el-icon-download" v-if="options.export"
              v-hasPermi="options.export.auth" @click="options.export.click">{{options.export.name || '导出' }}</el-button>
            <el-button type="danger" size="mini" icon="el-icon-delete" v-if="options.del"
              v-hasPermi="options.del.auth" :disabled="options.multiples.length === 0"
              @click="options.del.click">{{options.del.name || '批量删除' }}</el-button>
            <slot name="toolbarLeftEnd"></slot>
          </slot>
        </div>
        <div class="right">
          <slot name="toolbarRight">
            <slot name="toolbarRightStart"></slot>
            <el-popover
              placement="bottom-end"
              width="220"
              trigger="click"
              popper-class="popper-columns"
              v-model="visible"
              @hide="getPage()">
              <div class="columns-list">
                <div class="list-hd">表头设置</div>
                <div class="list-bd" ref="columnsList">
                  <div class="item" v-for="item in currentColumns" :key="item.name" v-show="item.isFilter">
                    <div class="item-left">
                      <i class="el-icon-rank" style="margin-right: 10px;"></i>
                      <label><el-checkbox v-model="item.visible">{{ item.label }}</el-checkbox></label>
                    </div>
                  </div>
                </div>
                <div class="list-ft">
                  <el-link :underline="false" @click="onResetColumns">重置</el-link>
                  <el-link :underline="false" @click="onSubmitColumns">确认</el-link>
                </div>
              </div>
              <template slot="reference">
                <el-tooltip class="item" effect="dark" content="筛选列" placement="top">
                  <el-button size="mini" circle icon="el-icon-s-grid" />
                </el-tooltip>
              </template>
            </el-popover>
            <ScreenFull :isEleFull.sync="isEleFull" />
            <el-tooltip v-if="options.serch" class="item" effect="dark" :content="options.serch.show ? '隐藏搜索' : '显示搜索'" placement="top">
              <el-button size="mini" circle icon="el-icon-search" @click="options.serch.click" />
            </el-tooltip>
            <slot name="toolbarRightEnd"></slot>
          </slot>
        </div>
      </div>
    </div>
    <div class="flex-bd" :id="ganttOptions.container" v-loading="options.loading" :style="{ height: isEleFull ? null : ganttOptions.height }"></div>
    <el-pagination 
      class="mt10 flex-ft"
      v-if="options.pageMethod"
      :background="true"
      :align="options.pageConfig.align || 'right'"
      :pageSizes="options.pageConfig.pageSizes || [10, 20, 50, 100, 200, 500, 1000]"
      :layout="options.pageConfig.layout || 'total, sizes, prev, pager, next, jumper'"
      :page-size="$parent.tableParams.pageSize" 
      :current-page="$parent.tableParams.pageNum"
      v-bind="options.pageConfig"
      v-on="options.pageMethod"
    />
  </div>
</template>
  
<script>
// (文档API) https://docs.dhtmlx.com/gantt/api__refs__gantt.html
import './dhtmlxgantt.v719.js'
import './dhtmlxgantt.v719.css'
import { deepCopy } from "@/utils/ruoyi"
import cache from '@/plugins/cache'
import ScreenFull from '@/components/Common/ScreenFull'
import Sortable from 'sortablejs'
export default {
  name: 'GanttList',
  components: {
    ScreenFull
  },
  props: ['options', 'ganttOptions'],
  data() {
    return {
      defaultOptions: {
        locale: {
          date: {
            month_full: ["01", "02", "03", "04", "05", "06", "07",
              "08", "09", "10", "11", "12"],
            month_short: ["01", "02", "03", "04", "05", "06", "07",
              "08", "09", "10", "11", "12"],
            day_full: ["星期日", "星期一", "星期二", "星期三", "星期四",
              "星期五", "星期六"],
            day_short: ["星期日", "星期一", "星期二", "星期三", "星期四",
              "星期五", "星期六"],
          },
        },
        config: {
          date_format: "%Y-%m-%d %H:%i",                        // 日期格式
          start_date: '',                                       // 设置开始时间
          end_date: '',                                         // 设置结束时间
          scale_height: 50,                                     // head总高度
          min_column_width: 40,                                 // head列宽
          row_height: 35,                                       // 行高度
          drag_links: false,                                    // 悬浮拖拽小圆圈
          drag_progress: false,                                 // 悬浮拖拽小三角   
          drag_move: false,                                     // 允许拖放移动任务
          drag_resize: false,                                   // 允许拖放调整任务大小
          round_dnd_dates: false,                               // 允许任务四舍五入临近线
          details_on_dblclick: false,                           // 双击打开弹窗
          container_resize_method: 'timeout',                   // 自动调整大小
        }
      },
      ganttInstance: null,
      isEleFull: false,
      visible: false,
      fullColumns: [],
      currentColumns: [],
      copyFullColumns: [],
      cachedPage: {
        all: [],
        current: null
      }
    }
  },
  computed: {
  },
  mounted() {
    for (let key in this.ganttOptions) {
      if (key === 'config') {
        for (let keys in this.ganttOptions.config) {
          this.defaultOptions.config[keys] = this.ganttOptions.config[keys]
        }
      } else {
        this.defaultOptions[key] = this.ganttOptions[key]
      }
    }
    this.ganttInstance = Gantt.getGanttInstance(this.defaultOptions)
    this.init()
    this.getPage()
    // 拖动宽度缓存
    this.ganttInstance.attachEvent("onColumnResizeEnd", (index, column, new_width) => {
      let current = this.currentColumns.find(v => v.name === column.name)
      current.width = new_width
      this.onSubmitColumns()
    })
  },
  watch: {
    'ganttOptions.data.tasks': {
      handler(newval, old) {
        if (this.ganttInstance != null) {
          this.ganttInstance.clearAll()
          this.ganttInstance.parse(this.ganttOptions.data)
        }
      },
      //immediate: true,
      //deep: true
    }
  },
  methods: {
    init() {
      this.fullColumns = this.ganttOptions.config.columns
      this.copyFullColumns = deepCopy(this.fullColumns)
      // 拖动
      this.$nextTick(() => {
        new Sortable(this.$refs['columnsList'], {
          animation: 150,
          ghostClass: 'blue-background-class',
          handle: ".el-icon-rank",
          onEnd: (evt) => {
            this.currentColumns.splice(evt.newIndex, 0, this.currentColumns.splice(evt.oldIndex, 1)[0]) 
          }
        })
      })
    },
    // 获取缓存的列数据
    getCached(){
      this.cachedPage.all = cache.local.getJSON('pageConfig') || []
      this.cachedPage.current = this.cachedPage.all.find(v => v.name === this.$parent.$options.name)
    },
    // 对比缓存，获取到最新的列数据
    getPage(){
      this.getCached()
      if(this.cachedPage.current){
        this.currentColumns = this.getNewColumns(deepCopy(this.copyFullColumns), this.cachedPage.current.columns)
      } else {
        this.currentColumns = this.getNewColumns(deepCopy(this.copyFullColumns), deepCopy(this.copyFullColumns))
      }
      this.getRefreshColumn()
    },
    // 获取最新的列数据
    getNewColumns(target, update){
      // 创建一个id到对象的映射，用于快速查找
      const idToObjectMap = new Map(target.map(obj => [obj.name, obj]));

      // 先处理缓存中的对象
      const newArray = update.map(obj => {
        // 如果缓存中的对象id在idToObjectMap中存在，返回该对象
        // 不存在过滤
        target.forEach(v => {
          if(obj.name === v.name){
            this.$set(v, 'visible', obj.visible)
            this.$set(v, 'width', obj.width)
          }
        })
        return idToObjectMap.get(obj.name) || {};
      }).filter(v => v.name)

      // 遍历默认列，找出那些还未在新数组中出现的对象
      // 根据默认列顺序插入
      target.forEach((obj,index) => {
        if (!newArray.some(newObj => newObj.name === obj.name)) {
          newArray.splice(index, 0, obj)
        }
      })
      return newArray
    },
    // 更新列
    getRefreshColumn(){
      this.$nextTick(() => {
        this.ganttInstance.config.columns = deepCopy(this.currentColumns).filter(v => v.visible)
        this.ganttInstance.render()
      })
    },
    // 重置列
    onResetColumns(){
      this.getCached()
      if(this.cachedPage.current){
        // 过滤缓存的列配置
        this.cachedPage.all = this.cachedPage.all.filter(v => v.name != this.$parent.$options.name)
        // 统一更新到local
        cache.local.setJSON('pageConfig', this.cachedPage.all)
      }
      // 关闭下拉，会自动更新列
      this.visible = false
      this.currentColumns = deepCopy(this.copyFullColumns)
      this.getRefreshColumn()
    },
    onSubmitColumns(){
      let columnsNew = this.currentColumns.filter(v => v.isFilter).map(v => {
        return {
          name: v.name,
          visible: v.visible,
          width: v.width
        }
      })
      this.getCached()
      // 存在缓存更新替换
      if(this.cachedPage.current){
        this.cachedPage.all.forEach(v => {
          if(v.name === this.$parent.$options.name){
            v.columns = columnsNew
          }
        })
      }else{// 不存在push
        this.cachedPage.all.push({
          name: this.$parent.$options.name,
          columns: columnsNew
        })
      }
      // 统一更新到local
      cache.local.setJSON('pageConfig', this.cachedPage.all)
      this.visible = false
      this.getRefreshColumn()
    }
  }
}
</script>

<style scoped lang="scss">
::v-deep {
  .gantt_container{
    width: 100% !important;
  }
  .gantt_grid_data .gantt_row.gantt_selected, .gantt_grid_data .gantt_row.odd.gantt_selected, .gantt_task_row.gantt_selected{
    background-color:#F5F7FA;
  }
  .gantt_grid_data .gantt_row.odd:hover,.gantt_grid_data .gantt_row:hover{
    background-color:#F5F7FA;
  }
  .gantt_task_row.gantt_selected .gantt_task_cell{
    border-right-color:#F5F7FA;
  }
  .gantt_grid_head_cell .gantt_sort{
    right: 10px;
    top: 50%;
    margin-top: -7px;
    pointer-events: none;
  }
  .gantt_grid_head_cell.sort{
    &:before{
      content: '';
      pointer-events: none;
      position: absolute;
      right: 10px;
      top: 50%;
      margin-top: -7px;
      width: 7px;
      height: 13px;
      background: url("~@/assets/images/caret.png") no-repeat;
      background-position: 50%;
    }
  }
  // .gantt_grid_head_cell{
  //   &:nth-child(n+2){
  //     border-left:#cecece 1px solid;
  //   }
  //   .sort{
  //     display: inline-block;
  //     vertical-align: middle;
  //     margin-top:-3px;
  //     cursor: pointer;
  //     i{
  //       display: block;
  //       line-height: 0.7;
  //     }
  //     .active{
  //       color: #1890ff;
  //     }
  //   }
  // }
  // .gantt_cell {
  //   text-align: center;
  //   .gantt_tree_content{
  //     overflow: hidden;
  //     white-space: nowrap;
  //     text-overflow: ellipsis;
  //   }
  // }
}
</style>
